以一個這樣的表單為例
<UserForm
:data="data"
@update:firstName="$store.commit('user', $event)"
@update:lastName="$store.commit('user', $event)"
@update:email="$store.commit('user', $event)"
@submit="onSubmit"
></UserForm>
data
會是以下面的 JSON 進行的設計
{
firstName: '',
lastName: '',
email: ''
}
按照前一篇文章介紹的邏輯,我們可以自由的決定「哪個欄位不要有寫入的權限」
透過改變 event 的欄位,決定相對應的欄位 disabled (其實也有其它的做法)
如下圖的三種改變
v-model
<UserForm
:data="data"
@update:firstName="$store.commit('user', $event)"
@update:lastName="$store.commit('user', $event)"
@update:email="$store.commit('user', $event)"
@submit="onSubmit"
></UserForm>
每一個 event 後面都是 $store.commit('user', $event)
這個是不是可以合併成相同的 event 反正後面接的語法都一樣,應該可以合併吧?而且 $event
用一個物件當輸入、用物件當輸出,怎麼不用 v-model
就好了?
<UserForm
:value="data"
@input="$store.commit('user', $event)"
@submit="onSubmit"
></UserForm>
可以,其實可以裡面只要這樣寫,就可以用 :value
+ @input
= v-model
每個 input 都這樣 @input="$emit('update:user')
觸動相同的 event 就可以做成 v-model
<UserForm
v-model="data"
@submit="onSubmit"
></UserForm>
src/components/UserForm.vue
component 裡面可以這樣實現 v-model 的做法
<input type="text"
:disabled="!$listeners['input']"
:value="value.firstName"
@input="$emit('input', {
...value,
firstName: $event.target.value
})">
<input type="text"
:disabled="!$listeners['input']"
:value="value.lastName"
@input="$emit('input', {
...value,
lastName: $event.target.value
})">
<input type="email"
:disabled="!$listeners['input']"
:value="value.email"
@input="$emit('input', {
...value,
email: $event.target.value
})">
缺點:
如果,不要物件進,物件出,而是讓各別的 event 吐出各別的值,那不就更接近原本的 form 表單控制?
src/components/UserForm.vue
那麼 component 裡面要這樣寫,就直覺多了。
<input type="text"
:disabled="!$listeners['update:firstName']"
:value="data.firstName"
@input="$emit('update:firstName', $event.target.value">
<input type="text"
:disabled="!$listeners['update:lastName']"
:value="data.lastName"
@input="$emit('update:lastName', $event.target.value">
<input type="email"
:disabled="!$listeners['update:email']"
:value="data.email"
@input="$emit('update:email', $event.target.value">
外面就得這樣用,將組出新 object 的責任放在外面,並且要用 immutable 的做法將 mutation 裡的值換掉,以確保會更新畫面。
<UserForm
:data="data"
@update:firstName="$store.commit('user', {
...data, firstName: $event })"
@update:lastName="$store.commit('user', {
...data, lastName: $event })"
@update:email="$store.commit('user', {
...data, email: $event })"
@submit="onSubmit"
></UserForm>
優點: 可以個別的控製各個欄位的讀寫權限
缺點: 使用表單時,要猜一下這次拿到的 $event 是什麼。或者要印出來看一下才可以確定
以補習班記口訣的方式來教學的,表單的 component 的設計,把握下列幾個重點。
原因在於,想要在 component 裡面控制各別的欄位寫入 JSON,並且傳出組好的新物件,也就不用在後面的資料流判斷這個欄位是屬於哪個物件,這種多餘的判斷或資料動態分流的邏輯。
<input type="text"
:disabled="!$listeners['update:firstName']"
:value="data.firstName"
@input="$emit('update:firstName', {
...data,
firstName: $event.target.value
})">
<input type="text"
:disabled="!$listeners['update:lastName']"
:value="data.lastName"
@input="$emit('update:lastName', {
...data,
lastName: $event.target.value
})">
<input type="email"
:disabled="!$listeners['update:email']"
:value="data.email"
@input="$emit('update:email', {
...data,
email: $event.target.value
})">